﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PerformanceAssessment.Models;

namespace PerformanceAssessment.Controllers
{
    public class ReportsController : Controller
    {
        private PerformanceAssessmentDB db = new PerformanceAssessmentDB();

        //
        // GET: /Reports/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult AssessmentStatusReport(int? periodId)
        {
            const string NOT_STARTED = "Not Started";
            const string IN_PROGRESS = "In Progress";
            const string PENDING_APPROVAL = "Pending Approval";
            const string COMPLETED = "Completed";

            List<AssessmentPeriod> periodList = db.AssessmentPeriods.OrderBy(p => p.FromDate).ToList();
            ViewBag.periodId = new SelectList(periodList, "ID", "Description", periodId);
            if (periodId != null)
            {
                AssessmentPeriod period = db.AssessmentPeriods
                    .Include("Teams")
                    .Include("Teams.Employees")
                    .Include("Assessments")
                    .Include("Assessments.SkillAssessments")
                    .Where(p => p.ID == periodId )
                    .FirstOrDefault();

                if (period == null)
                    return View();
                
                List<StatusReportModel> statuses = new List<StatusReportModel>();
                float totalSum = 0;
                int avCount = 0;

                foreach (Team team in period.Teams)
                {
                    foreach (Employee employee in team.Employees)
                    {
                        if (employee.Active == true)
                        {
                            StatusReportModel model = new StatusReportModel();
                            model.Employee = string.Format("{0} {1}", employee.FirstName, employee.FirstLastName);
                            model.ContractorId = employee.IdContractor;
                            model.Evaluation = 0;


                            Assessment assessment = period.Assessments.Where(a => a.IdEmployee == employee.ID).FirstOrDefault();
                            if (assessment != null)
                            {
                                switch ((AssessmentStatus)assessment.IdAssessmentStatus)
                                {
                                    case AssessmentStatus.AutoEvaluationOpened:
                                        model.Autoevaluation = IN_PROGRESS;
                                        model.ManagerEvaluation = NOT_STARTED;
                                        model.PADone = IN_PROGRESS;
                                        break;
                                    case AssessmentStatus.AutoEvaluationCompleted:
                                        model.Autoevaluation = PENDING_APPROVAL;
                                        model.ManagerEvaluation = NOT_STARTED;
                                        model.PADone = IN_PROGRESS;
                                        break;
                                    case AssessmentStatus.AutoEvaluationApproved:
                                        model.Autoevaluation = COMPLETED;
                                        model.ManagerEvaluation = IN_PROGRESS;
                                        model.PADone = IN_PROGRESS;
                                        break;
                                    case AssessmentStatus.ManagerAssessmentCompleted:
                                        model.Autoevaluation = COMPLETED;
                                        model.ManagerEvaluation = PENDING_APPROVAL;
                                        model.PADone = IN_PROGRESS;
                                        break;
                                    case AssessmentStatus.Disagreement:
                                        model.Autoevaluation = IN_PROGRESS;
                                        model.ManagerEvaluation = PENDING_APPROVAL;
                                        model.PADone = IN_PROGRESS;
                                        break;
                                    case AssessmentStatus.DisagreementSolved:
                                        model.Autoevaluation = PENDING_APPROVAL;
                                        model.ManagerEvaluation = PENDING_APPROVAL;
                                        model.PADone = IN_PROGRESS;
                                        break;
                                    case AssessmentStatus.Completed:
                                        model.Autoevaluation = model.ManagerEvaluation = model.PADone = COMPLETED;

                                        int count = 0;
                                        foreach (SkillAssessment sa in assessment.SkillAssessments)
                                        {
                                            //Avoids adding the skills with score 0 in the sum and the average
                                            if (sa.ManagerScore != null && sa.ManagerScore.Value != 0)
                                            {
                                                model.Evaluation += sa.ManagerScore.Value;
                                                count++;
                                            }
                                        }
                                        if (count > 0)
                                            model.Evaluation /= count;
                                        totalSum += model.Evaluation;
                                        avCount++;
                                        break;
                                }
                            }
                            else
                            {
                                model.Autoevaluation = model.ManagerEvaluation = model.PADone = NOT_STARTED;
                            }
                            statuses.Add(model);
                        }
                    }
                }

                if (avCount != 0)
                    totalSum /= avCount;
                foreach (StatusReportModel s in statuses)
                {
                    s.Average = totalSum;
                }

                return View(statuses);
            }
            return View();
        }

        public ActionResult SkillScoresReport(int? periodId)
        {
            List<AssessmentPeriod> periodList = db.AssessmentPeriods.OrderBy(p => p.FromDate).ToList();
            ViewBag.periodId = new SelectList(periodList, "ID", "Description", periodId);
            if (periodId != null)
            {
                AssessmentPeriod period = (from p in db.AssessmentPeriods.Include("Assessments")
                                           .Include("Assessments.Employee")
                                           .Include("Assessments.SkillAssessments")
                                           where p.ID == periodId
                                           select p).FirstOrDefault();

                if (period == null)
                    return View();
                           
                List<Skill> availableSkills = (from p in db.AssessmentPeriods
                                                    from t in p.Teams
                                                    join st in db.SkillsPerTeam on t.ID equals st.IdTeam
                                                    join s in db.Skills on st.IdSkill equals s.ID
                                                    where p.ID == periodId
                                                    orderby s.ID
                                                    select s).Distinct().ToList();
                ViewBag.skills = availableSkills;
                List<SkillScoresModel> scores = new List<SkillScoresModel>();
                float totalSum = 0;
                foreach (Assessment assessment in period.Assessments)
                {
                    if (assessment.IdAssessmentStatus == (int)AssessmentStatus.Completed)
                    {
                        SkillScoresModel model = new SkillScoresModel();
                        model.Employee = string.Format("{0} {1}", assessment.Employee.FirstName, assessment.Employee.FirstLastName);
                        model.Scores = new List<int>();
                        model.Total = 0;
                        int count = 0;
                        foreach (Skill skill in availableSkills)
                        {
                            SkillAssessment sa = assessment.SkillAssessments.Where(s => s.IdSkill == skill.ID).FirstOrDefault();
                            //Avoids adding the skills with score 0 in the sum and the average
                            if (sa != null && sa.ManagerScore != null && sa.ManagerScore.Value != 0)
                            {
                                model.Scores.Add(sa.ManagerScore.Value);
                                model.Total += sa.ManagerScore.Value;
                                count++;
                            }
                            else
                            {
                                model.Scores.Add(0);
                            }
                        }
                        model.Score = (float) model.Total / count;
                        totalSum += model.Score;
                        scores.Add(model);
                    }
                }
                totalSum /= scores.Count;
                foreach (SkillScoresModel ssm in scores)
                {
                    ssm.Average = totalSum;
                }
                return View(scores);
            }
            return View();
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

    }
}
